import datetime
from django.db import models
from django.utils import timezone

from markdownx.models import MarkdownxField
from markdownx.utils import markdownify

from common.models import TimeStampedModel
from course.models import Course
from user.models import User


class Exam(models.Model):
    course = models.ForeignKey(Course, related_name='exams')
    title = models.CharField(max_length=200)
    start = models.DateTimeField()
    end = models.DateTimeField()

    started = models.BooleanField(default=False)
    started_time = models.DateTimeField(null=True)

    def to_obj(self):
        obj = {}
        obj['id'] = self.pk
        obj['title'] = self.title
        obj['start'] = int(self.start.timestamp() * 1e3)
        obj['end'] = int(self.end.timestamp() * 1e3)
        obj['zone'] = self.course.course_zone
        return obj

    def update_problems(self):
        start = self.started_time
        for problem in self.problems.all():
            if self.started:
                problem.start = start
                start = start + datetime.timedelta(
                    minutes=problem.minutes)
            else:
                problem.start = None
            problem.save()

    def is_ended(self):
        last_problem = self.problems.order_by('-start').first()
        if not last_problem.start:
            return False
        dt = last_problem.start + datetime.timedelta(
            minutes=last_problem.minutes)
        return timezone.now() > dt


class Problem(models.Model):
    exam = models.ForeignKey(Exam, related_name='problems')
    content = MarkdownxField()
    full_marks = models.IntegerField(blank=True, null=True)
    start = models.DateTimeField(blank=True, null=True)
    minutes = models.IntegerField()

    @property
    def formatted_markdown(self):
        return markdownify(self.content)


class ExamPaperManager(models.Manager):

    def init_exam_paper(self, exam, user):
        exam_paper, created = ExamPaper.objects.get_or_create(
                                    exam=exam,
                                    student=user,
                                )


class ExamPaper(models.Model):
    exam = models.ForeignKey(
        Exam,
        related_name='exam_papers',
        on_delete=models.CASCADE
    )
    student = models.ForeignKey(
        User,
        related_name='exam_papers',
        on_delete=models.CASCADE,
    )

    total_score = models.IntegerField(blank=True, null=True)
    comment = models.TextField(blank=True, null=True)

    objects = ExamPaperManager()


class AnswerManager(models.Manager):

    def init_answer(self, exam_paper):
        for problem in exam_paper.exam.problems.all():
            new_answer, created = Answer.objects.get_or_create(
                                    exam_paper=exam_paper,
                                    problem=problem
            )
            if created:
                new_answer.content = 'not answered yet'
                new_answer.amendment = 'not inputed yet'
                new_answer.save()


class Answer(models.Model):
    exam_paper = models.ForeignKey(
        ExamPaper,
        related_name='answers'
    )
    content = models.TextField()
    problem = models.ForeignKey(
        Problem, related_name='answers')
    amendment = models.TextField(blank=True, null=True)
    score = models.IntegerField(default=0)

    objects = AnswerManager()


class InlineComment(TimeStampedModel):
    answer = models.ForeignKey(Answer, related_name='inline_comments')
    linenum = models.IntegerField()
    content = models.TextField()
    commenter = models.ForeignKey(User, related_name='inline_comments')
    is_amendment = models.BooleanField(default=False)

    def __str__(self):
        return self.content
